#include "stdafx.h"

#include <MyFC/DoublyLabelledWidget.h>
#include <MyFC/Utility.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

namespace My {

DoublyLabelledWidget::DoublyLabelledWidget()
{
	m_pWidget = 0;
	m_Alignment = ALIGN_HLEFT|ALIGN_VCENTER;
	m_TextRect[LeftSide] = m_TextRect[RightSide] = CRect(0, 0, 0, 0);
}

void DoublyLabelledWidget::SetWidget(Widget * pWidget)
{
	if (pWidget != m_pWidget) {
		if (m_pWidget != 0)
			Remove(m_pWidget);
		m_pWidget = pWidget;
		if (m_pWidget != 0)
			Add(m_pWidget);
		LayoutControls();
	}
}

void DoublyLabelledWidget::SetText(int side, const String & s)
{
	if (s != m_Text[side]) {
		m_Text[side] = s;
		LayoutControls();
	}
}

void DoublyLabelledWidget::SwapTexts()
{
	m_Text[LeftSide].swap(m_Text[RightSide]);
	LayoutControls();
}

void DoublyLabelledWidget::SetAlignment(int a)
{
	if (a != m_Alignment) {
		m_Alignment = a;
		LayoutControls();
	}
}

void DoublyLabelledWidget::HandleFont()
{
	LayoutControls();
}

void DoublyLabelledWidget::GetSizes(CDC & dc, CSize & sAll, CSize & sWidget, CSize sText[2]) const
{
	for (int side = 0; side < 2; ++side) {
		if (!m_Text[side].empty())
			sText[side] = dc.GetTextExtent(m_Text[side].c_str(), m_Text[side].size());
		else
			sText[side] = CSize(0, 0);
	}

	if (m_pWidget != 0)
		sWidget = m_pWidget->GetPreferredSize();
	else
		sWidget = CSize(0, 0);

	int gap = 0;
	if (m_pWidget != 0) {
		if (HasLabel(LeftSide))
			gap += 4;
		if (HasLabel(RightSide))
			gap += 4;
	}

	sAll = sWidget;
	sAll.cx += gap + sText[LeftSide].cx + sText[RightSide].cx;
	if (sText[LeftSide].cy > sAll.cy)
		sAll.cy = sText[LeftSide].cy;
	if (sText[RightSide].cy > sAll.cy)
		sAll.cy = sText[RightSide].cy;
}

CSize DoublyLabelledWidget::GetPreferredSize() const
{
	My::ClientDC dc(const_cast<DoublyLabelledWidget *>(this));
	My::SaveObjects save(&dc);

	CSize sAll, sWidget, sText[2];
	GetSizes(dc, sAll, sWidget, sText);

	return sAll;
}

void DoublyLabelledWidget::LayoutControls()
{
	My::ClientDC dc(this);
	My::SaveObjects save(&dc);

	CRect rClient = ClientRect();
	SelectFont(&dc);

	CSize sAll, sWidget, sText[2];
	GetSizes(dc, sAll, sWidget, sText);

	CRect rAll(CPoint(0, 0), sAll);
	rAll = AlignRect(rClient, rAll, m_Alignment);
	rAll.IntersectRect(&rAll, &rClient);

	CRect rWidget(0, 0, 0, 0);
	rWidget.right = sWidget.cx;
	if (rAll.Width() < rWidget.right)
		rWidget.right = rAll.Width();
	rWidget.bottom = sWidget.cy;
	if (rAll.Height() < rWidget.bottom)
		rWidget.bottom = rAll.Height();

	int LeftGap = (m_pWidget != 0 && HasLabel(LeftSide)) ? 4 : 0;
	CRect & rLeft = m_TextRect[LeftSide];
	rLeft.left = rLeft.top = 0;
	rLeft.right = sText[LeftSide].cx;
	if (rAll.Width() - rWidget.Width() - LeftGap < rLeft.right)
		rLeft.right = rAll.Width() - rWidget.Width() - LeftGap;
	rLeft.bottom = sText[LeftSide].cy;
	if (rAll.Height() < rLeft.bottom)
		rLeft.bottom = rAll.Height();
	int width2 = rWidget.Width() + LeftGap + rLeft.right;

	int RightGap = (m_pWidget != 0 && HasLabel(RightSide)) ? 4 : 0;
	CRect & rRight = m_TextRect[RightSide];
	rRight.left = rRight.top = 0;
	rRight.right = sText[RightSide].cx;
	if (rAll.Width() - width2 - RightGap < rRight.right)
		rRight.right = rAll.Width() - width2 - RightGap;
	rRight.bottom = sText[RightSide].cy;
	if (rAll.Height() < rRight.bottom)
		rRight.bottom = rAll.Height();

	rLeft = AlignRect(rAll, rLeft, ALIGN_HLEFT|ALIGN_VCENTER);
	rWidget = AlignRect(rAll, rWidget, ALIGN_HCENTER|ALIGN_VCENTER);
	rRight = AlignRect(rAll, rRight, ALIGN_HRIGHT|ALIGN_VCENTER);

	int delta = rWidget.left - rLeft.right - LeftGap;
	rWidget.left -= delta;
	rWidget.right -= delta;

	if (m_pWidget != 0)
		m_pWidget->SetBounds(rWidget);

	Invalidate();
}

void DoublyLabelledWidget::HandlePaint(CDC * pDC, const CRect & r)
{
	if (!HasAnyLabel())
		return;

	//My::SaveObjects save(pDC);

	COLORREF OldTextColor;

	if (ControlEnabled(m_pWidget))
		OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
	else
		OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_BTNSHADOW));

	int OldBkMode = pDC->SetBkMode(TRANSPARENT);

	for (int side = 0; side < 2; ++side) {
		if (HasLabel(side))
			pDC->DrawText(m_Text[side].c_str(), &m_TextRect[side], DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_END_ELLIPSIS);
	}

	pDC->SetBkMode(OldBkMode);
	pDC->SetTextColor(OldTextColor);
}

void DoublyLabelledWidget::HandleUpdateUI()
{
	Invalidate();
}


} // My
